/**
 *
 */
package com.yswy.domain.common.util;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

/**
 * 时间工具类
 */
public class DateUtils {
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 一堆日期里面最小的
     *
     * @param dates
     * @return
     */
    public static Date min(Date... dates) {
        Arrays.sort(dates);
        return dates[0];
    }

    /**
     * 一堆日期里面最大的
     *
     * @param dates
     * @return
     */
    public static Date max(Date... dates) {
        Arrays.sort(dates);
        return dates[dates.length - 1];
    }

    /**
     * 对时间取整 22.30 -> 22.00
     */
    public static Date roundingTime(Date date) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(date);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        return calendat.getTime();
    }

    /**
     * 小于a小时之前的数据
     */
    public static Date beforeHourTime(int a) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        calendat.add(Calendar.HOUR_OF_DAY, a);
        return calendat.getTime();
    }

    /**
     * 小于a天的日期，比如金坛是7月3号， 如果a=1 则返回7月4号
     */
    public static Date beforeDayTime(int a) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        calendat.add(Calendar.DAY_OF_YEAR, a);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        return calendat.getTime();
    }

    /**
     * 得到分析时间 true AM false pm
     */
    public static boolean getAmPm() {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        if (calendat.get(Calendar.HOUR_OF_DAY) > 12) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 得到分析时间
     */
    public static Date getAnalyzeTime() {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        if (calendat.get(Calendar.HOUR_OF_DAY) > 12) {
            calendat.set(Calendar.HOUR_OF_DAY, 12);
        } else {
            calendat.set(Calendar.HOUR_OF_DAY, 0);
        }
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        return calendat.getTime();
    }

    /**
     * 返回当日的时间（以i递增）
     */
    public static Date[] getTimeByTime(Date date, int t) {
        int h = 0;
        Date[] dates = new Date[(24 / t) + 1];
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(date);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        for (int i = 0; h <= 24; i++) {
            dates[i] = calendat.getTime();
            calendat.set(Calendar.HOUR_OF_DAY, h += t);
        }
        return dates;
    }

    public static Date getLastWeekToday() {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        calendat.add(Calendar.DAY_OF_YEAR, -7);
        Date sdate = calendat.getTime();
        return sdate;
    }

    public static int getYear(Date date) {
        return getByFiled(date, Calendar.YEAR);
    }

    public static int getMonth(Date date) {
        //月份从0开始
        return getByFiled(date, Calendar.MONTH) + 1;
    }

    public static int getDay(Date date) {
        return getByFiled(date, Calendar.DAY_OF_MONTH);
    }

    public static int getByFiled(Date date, int filed) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(date);
        return calendat.get(filed);
    }

    /**
     * 返回当日的00:00:00和23:59:59
     */
    public static Date[] getDateSE(Date date) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(date);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        Date sdate = calendat.getTime();
        calendat.set(Calendar.HOUR_OF_DAY, 24);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        Date edate = calendat.getTime();
        return new Date[]{sdate, edate};
    }

    public static String returnDate(int count) {
        Calendar strDate = Calendar.getInstance();
        strDate.add(Calendar.DATE, count);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(strDate.getTime());
    }

    /**
     * 指定日期加一天，并且0点0分
     * @param startDate
     * @param count
     * @return
     */
    public static Date getAddDate(Date startDate, int count) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(startDate);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);
        calendat.set(Calendar.MILLISECOND, 0);
        calendat.add(Calendar.DATE, count);
        return calendat.getTime();
    }

    /**
     * 指定日期加一天，yy-mm-dd hh:mm:ss
     * @param startDate
     * @param count
     * @return
     */
    public static Date getAddDateTime(Date startDate, int count) {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(startDate);
        calendat.add(Calendar.DATE, count);
        return calendat.getTime();
    }


    public static String formatYM2() {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        calendat.add(Calendar.MONTH, -1);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);

        SimpleDateFormat sdf = new SimpleDateFormat("yyMM");
        return sdf.format(calendat.getTime());
    }

    public static String formatYM() {
        Calendar calendat = Calendar.getInstance();
        calendat.setTime(new Date());
        calendat.add(Calendar.MONTH, -1);
        calendat.set(Calendar.HOUR_OF_DAY, 0);
        calendat.set(Calendar.MINUTE, 0);
        calendat.set(Calendar.SECOND, 0);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(calendat.getTime());
    }

    public static String format(Date date , String Format) {
        SimpleDateFormat sdf = new SimpleDateFormat(Format);
        return sdf.format(date);
    }


    /**
     * 返回当前时间是一年中的第几天
     * @param date
     * @return
     */
    public static int formatDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        int i = ca.get(Calendar.DAY_OF_YEAR);
        return i;
    }

    /**
     * (格林标准时间)Mon, 17 Feb 2014 13:53:32 +0000类型时间转yyyy-MM-dd HH:mm:ss
     * @author kangdong
     * @date 2019/3/15
     * @param param Mon, 17 Feb 2014 13:53:32 +0000
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String formatDateTime(String param) {
        Date d5 = new Date(param);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(d5);
        return date;
    }



    /**
     * （CST是（美）中央时区）Mon Mar 25 14:29:39 CST 2019类型时间转yyyy-MM-dd HH:mm:ss
     * @author kangdong
     * @date 2019/3/15
     * @param param Mon, 17 Feb 2014 13:53:32 +0000
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String formatCstDateTime(String param) {
        String date = null;
        try {
            SimpleDateFormat sfEnd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sfStart = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",java.util.Locale.ENGLISH) ;
            date = sfEnd.format(sfStart.parse(param));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


//    方式一的话，只是通过日期来进行比较两个日期的相差天数的比较，没有精确到相差到一天的时间。
//    如果是只是纯粹通过日期（年月日）来比较比较的话就是方式一。
//　　对于方式二，是通过计算两个日期相差的毫秒数来计算两个日期的天数差的。一样会有一个小问题，
// 就是当他们相差是23个小时的时候，它就不算一天了。如下面的两个日期
    /**
     * date2比date1多的天数
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1,Date date2)
    {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)   //同一年
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)    //闰年
                {
                    timeDistance += 366;
                }
                else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2-day1) ;
        }
        else    //不同年
        {
//            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2-day1;
        }
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1,Date date2)
    {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }

    /**
     * 比较两个时间相差的分钟数
     */
    public static int differentDaysByMinute(Date date2) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long currentTime =System.currentTimeMillis();
        //从对象中拿到时间
        long createTime = df.parse(df.format(date2)).getTime();
        long diff=(currentTime-createTime)/1000/60;
        System.out.println("当前系统时间为："+currentTime+"对象时间为："+createTime+"两个时间差为："+diff);
        return (int) diff;
    }

    /**
     * @Description  ：获取当前时间前x分钟的时间
     * @author       : zhuoxiaoya
     * @exception    :
     */

    public static String getDateBefore(int min){
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.add(Calendar.MINUTE, min);// 5分钟之前的时间
        Date beforeD = beforeTime.getTime();
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(beforeD);
    }




    /**
     * @Description  ：返回两个时间段之间的随机一个时间
     * @author       : zhuoxiaoya
     * @exception    :
     */
    public static Date randomDate(String beginDate,String endDate){
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date start = format.parse(beginDate);
            Date end = format.parse(endDate);

            if(start.getTime() >= end.getTime()){
                return null;
            }
            long date = random(start.getTime(),end.getTime());
            return new Date(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static long random(long begin,long end){
        long rtn = begin + (long)(Math.random() * (end - begin));
        if(rtn == begin || rtn == end){
            return random(begin,end);
        }
        return rtn;
    }

    public static String formatDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(date);
    }

    /**
     * date转string
     * @param date
     * @return
     */
    public static String getNowDate(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(date);
        return dateString;
    }

    //指定日期加上指定天数得到新日期
    public static Date addDate(Date date, long day,Integer type) {
        long time = date.getTime(); // 得到指定日期的毫秒数
        day = day * 24 * 60 * 60 * 1000; // 要加上的天数转换成毫秒数
        if(type == 1 ){
            time += day; // 相加得到新的毫秒数
        }else {
            time -= day; // 相减得到新的毫秒数
        }
        return new Date(time); // 将毫秒数转换成日期
    }



    //指定日期加上指定月数得到新日期
    public static Date stepMonth(Date sourceDate, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }
    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }


    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    /**
     * @param days  增加天数  1  /  -1
     * @param date   DateUtils.getDate()
     * @return
     * @throws ParseException
     */
    public static String setDateDays(int days,String date) throws ParseException {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        cal.setTime(sdf.parse(date));//设置起时间
        cal.add(Calendar.DATE, days);//增加一天
        return sdf.format(cal.getTime());
    }

    /**
     * @author bing
     * @param hours:
     * @param date:
     * @Description:  增加时间，小时
     * @date 2022/3/9 14:55
     * @return: java.lang.String
     */
    public static String setDateHours(int hours,String date) throws ParseException {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        //设置起时间
        cal.setTime(sdf.parse(date));
        //增加时间（小时）
        cal.add(Calendar.HOUR_OF_DAY, hours);
        return sdf.format(cal.getTime());
    }


    public static String firstDay(){
        Calendar cal = Calendar.getInstance();
        //获取本月第一天
        cal.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }


}
